package model.ability;

import java.util.Random;

/**
 * Base class for the Ability hierarchy.
 * @author Zachary
 *
 */
public abstract class Ability implements Cloneable{
	private String name;
	private PassiveSkill governingSkill;
	private int manaCost;
	private int delay;
	
	/**
	 * Constructor for Ability - only used in subclass constructors.
	 * @param name
	 * @param ps
	 * @param mana
	 * @param delay
	 */
	protected Ability(String name, PassiveSkill ps, int mana, int delay){
		this.name = name;
		this.governingSkill = ps;
		this.manaCost = mana;
		this.delay = delay;
	}
	
	/**
	 * Calculates a multiplier based on the PassiveSkill skill level.
	 * @return
	 */
	protected double getSkillLevelMultiplier(){
		return (this.getGoverningSkillLevel() / (this.getGoverningSkillMaxLevel() / 10)) + 1;
	}
	
	/**
	 * Calculate the probability of a successful ability use.
	 * Based on the PassiveSkill level and is in the range
	 * [25 100] in R (as approximated by double).
	 * 
	 * To use this probability, get a random integer from 0 to 100.
	 * If it is less than the value returned from this method, do your
	 * action, otherwise do nothing.
	 * @return
	 */
	protected double getSuccessProbability(){
		double probFactor = (1 / (this.getGoverningSkillMaxLevel() - this.getGoverningSkillLevel() + 1));
		double random = Math.max(Math.random(), .25);
		return Math.max(random + probFactor, 1) * 100;
	}
	
	/**
	 * Use this method to determine if an ability works.  Returns
	 * a boolean based on the success probability of the ability which
	 * is based on the caster's skill level.
	 * @return
	 */
	public boolean testProbability(){
		int prob = (int)this.getSuccessProbability();
		Random rand = new Random();
		int testValue = rand.nextInt(100);
		return testValue < prob;
	}
	
	/**
	 * Get the name of the ability.
	 * @return
	 */
	public String getName(){
		return this.name;
	}
	
	/**
	 * Get the name of the governing passive skill.
	 * @return
	 */
	public String getGoverningSkillName(){
		return this.governingSkill.getName();
	}
	
	/**
	 * Get the level of the governing passive skill.
	 * @return
	 */
	public int getGoverningSkillLevel(){
		return this.governingSkill.getLevel();
	}
	
	/**
	 * Get the max governing skill level.
	 * @return
	 */
	public int getGoverningSkillMaxLevel(){
		return this.governingSkill.getMAXLEVEL();
	}
	
	/**
	 * Get the mana cost of using this ability.
	 * @return
	 */
	public int getManaCost(){
		return this.manaCost;
	}
	
	/**
	 * Get the delay amount for using this ability.
	 * @return
	 */
	public int getDelay(){
		return this.delay;
	}
	
	/**
	 * Get the governing passive skill.
	 * @param skill
	 */
	public void setGoverningSkill(PassiveSkill skill){
		this.governingSkill = skill;
	}

	/**
	 * Clone the Ability.
	 */
	public Ability clone(){
		try{
			Ability cloned = (Ability)super.clone();
			return cloned;
		}catch(CloneNotSupportedException e){
			System.out.println(e);
			return null;
		}
    }
}
